import 'dart:convert';
import 'dart:developer';

void tryCatch(Function? f) {
  try {
    f?.call();
  } catch (e, stack) {
    log('$e');
    log('$stack');
  }
}

class FFConvert {
  FFConvert._();

  static T? Function<T extends Object?>(dynamic value) convert = <T>(dynamic value) {
    if (value == null) {
      return null;
    }
    return json.decode(value.toString()) as T?;
  };
}

T? asT<T extends Object?>(dynamic value, [T? defaultValue]) {
  if (value is T) {
    return value;
  }
  try {
    if (value != null) {
      final String valueS = value.toString();
      if ('' is T) {
        return valueS as T;
      } else if (0 is T) {
        return int.parse(valueS) as T;
      } else if (0.0 is T) {
        return double.parse(valueS) as T;
      } else if (false is T) {
        if (valueS == '0' || valueS == '1') {
          return (valueS == '1') as T;
        }
        return (valueS == 'true') as T;
      } else {
        return FFConvert.convert<T>(value);
      }
    }
  } catch (e, stackTrace) {
    log('asT<$T>', error: e, stackTrace: stackTrace);
    return defaultValue;
  }

  return defaultValue;
}

class SaleProject {
  SaleProject({
    required this.id,
    required this.company,
    required this.saleProjectNo,
    required this.projectNo,
    required this.projectName,
    required this.applyDate,
    required this.applyEmp,
    required this.marketArea,
    required this.areaDept,
    required this.bidStatus,
    required this.ownUnit,
    required this.designUnit,
    required this.contractUnit,
    required this.bidUnit,
    required this.buildAddress,
    required this.buildStage,
    required this.beginTime,
    required this.endTime,
    required this.buildDesc,
    required this.buildType,
    required this.projectCategory,
    required this.chargeDept,
    required this.projectSource,
    required this.bidMode,
    this.otherDoc,
    this.projectSumAmount,
    this.projectProfitRate,
    this.projectExpenseAmount,
    required this.processStatus,
    required this.contractStatus,
    this.createEmp,
    this.createTime,
    this.updateEmp,
    this.updateTime,
  });

  factory SaleProject.fromJson(Map<String, dynamic> jsonRes) => SaleProject(
        id: asT<int>(jsonRes['id'])!,
        company: asT<String>(jsonRes['company'])!,
        saleProjectNo: asT<String>(jsonRes['saleProjectNo'])!,
        projectNo: asT<String>(jsonRes['projectNo'])!,
        projectName: asT<String>(jsonRes['projectName'])!,
        applyDate: asT<String>(jsonRes['applyDate'])!,
        applyEmp: asT<String>(jsonRes['applyEmp'])!,
        marketArea: asT<String>(jsonRes['marketArea'])!,
        areaDept: asT<String>(jsonRes['areaDept'])!,
        bidStatus: asT<String>(jsonRes['bidStatus'])!,
        ownUnit: asT<String>(jsonRes['ownUnit'])!,
        designUnit: asT<String>(jsonRes['designUnit'])!,
        contractUnit: asT<String>(jsonRes['contractUnit'])!,
        bidUnit: asT<String>(jsonRes['bidUnit'])!,
        buildAddress: asT<String>(jsonRes['buildAddress'])!,
        buildStage: asT<String>(jsonRes['buildStage'])!,
        beginTime: asT<String>(jsonRes['beginTime'])!,
        endTime: asT<String>(jsonRes['endTime'])!,
        buildDesc: asT<String>(jsonRes['buildDesc'])!,
        buildType: asT<String>(jsonRes['buildType'])!,
        projectCategory: asT<String>(jsonRes['projectCategory'])!,
        chargeDept: asT<String>(jsonRes['chargeDept'])!,
        projectSource: asT<String>(jsonRes['projectSource'])!,
        bidMode: asT<String>(jsonRes['bidMode'])!,
        otherDoc: asT<String?>(jsonRes['otherDoc']),
        projectSumAmount: asT<double?>(jsonRes['projectSumAmount']),
        projectProfitRate: asT<double?>(jsonRes['projectProfitRate']),
        projectExpenseAmount: asT<double?>(jsonRes['projectExpenseAmount']),
        processStatus: asT<int>(jsonRes['processStatus'])!,
        contractStatus: asT<int>(jsonRes['contractStatus'])!,
        createEmp: asT<String?>(jsonRes['createEmp']),
        createTime: asT<String?>(jsonRes['createTime']),
        updateEmp: asT<String?>(jsonRes['updateEmp']),
        updateTime: asT<String?>(jsonRes['updateTime']),
      );

  int id;
  String company;
  String saleProjectNo;
  String projectNo;
  String projectName;
  String applyDate;
  String applyEmp;
  String marketArea;
  String areaDept;
  String bidStatus;
  String ownUnit;
  String designUnit;
  String contractUnit;
  String bidUnit;
  String buildAddress;
  String buildStage;
  String beginTime;
  String endTime;
  String buildDesc;
  String buildType;
  String projectCategory;
  String chargeDept;
  String projectSource;
  String bidMode;
  String? otherDoc;
  double? projectSumAmount;
  double? projectProfitRate;
  double? projectExpenseAmount;
  int processStatus;
  int contractStatus;
  String? createEmp;
  String? createTime;
  String? updateEmp;
  String? updateTime;

  @override
  String toString() {
    return jsonEncode(this);
  }

  Map<String, dynamic> toJson() => <String, dynamic>{
        'id': id,
        'company': company,
        'saleProjectNo': saleProjectNo,
        'projectNo': projectNo,
        'projectName': projectName,
        'applyDate': applyDate,
        'applyEmp': applyEmp,
        'marketArea': marketArea,
        'areaDept': areaDept,
        'bidStatus': bidStatus,
        'ownUnit': ownUnit,
        'designUnit': designUnit,
        'contractUnit': contractUnit,
        'bidUnit': bidUnit,
        'buildAddress': buildAddress,
        'buildStage': buildStage,
        'beginTime': beginTime,
        'endTime': endTime,
        'buildDesc': buildDesc,
        'buildType': buildType,
        'projectCategory': projectCategory,
        'chargeDept': chargeDept,
        'projectSource': projectSource,
        'bidMode': bidMode,
        'otherDoc': otherDoc,
        'projectSumAmount': projectSumAmount,
        'projectProfitRate': projectProfitRate,
        'projectExpenseAmount': projectExpenseAmount,
        'processStatus': processStatus,
        'contractStatus': contractStatus,
        'createEmp': createEmp,
        'createTime': createTime,
        'updateEmp': updateEmp,
        'updateTime': updateTime,
      };

  SaleProject clone() => SaleProject.fromJson(asT<Map<String, dynamic>>(jsonDecode(jsonEncode(this)))!);
}
